#include <iostream>
#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/RollingFileAppender.hh>
using namespace log4cpp;
using namespace std;
class Mylogger
{
public:
	void warn(const char *msg);
	void error(const char *msg);
	void debug(const char *msg);
	void info(const char *msg);
	void crit(const char *msg);
	void fatal(const char *msg);
   /* static Mylogger* getInstance(){
        //获取记录器对象 
        static Mylogger log;            
        return &log;
    }*/
    static Mylogger* getInstance(){
        if(!_plog){
          _plog = new Mylogger();

        }
        return _plog;
    }
private:
	Mylogger();
	~Mylogger();
    
private:
  //......
  Category *salesDepart;
    static Mylogger*_plog;
};
Mylogger* Mylogger::_plog = nullptr;
void Mylogger::warn(const char *msg){
    salesDepart->warn(msg);
}
void Mylogger::error(const char *msg){
    salesDepart->error(msg);
}
void Mylogger::debug(const char *msg){         
    salesDepart->debug(msg);
}
void Mylogger::info(const char *msg){         
    salesDepart->info(msg);
}
void Mylogger::crit(const char *msg){         
    salesDepart->crit(msg);
}
void Mylogger::fatal(const char *msg){         
    salesDepart->fatal(msg);
}

Mylogger::Mylogger(){
     //设置日志布局
 PatternLayout *ptn1 = new PatternLayout();
 //布局指针和对应布局关联设置
 ptn1->setConversionPattern("%d %c [%p] %m%n");

 PatternLayout *ptn2 = new PatternLayout();
 ptn2->setConversionPattern("%d %c [%p] %m%n");

 PatternLayout *ptn3 = new PatternLayout();
 ptn3->setConversionPattern("%d %c [%p] %m%n");
 //设置 目的 包括 是终端还是文件
 //第二个参数是输出的地方 第一个是 自己设置的名字
 OstreamAppender *pos = new OstreamAppender("first",&cout);
 pos->setLayout(ptn1);

 FileAppender *fpos = new FileAppender("first","logged.txt");
 fpos->setLayout(ptn2);
 //设置回卷
 RollingFileAppender *rfPos = new RollingFileAppender("rollingfill"
                                                      ,"RollingFill.log"
                                                      ,5*1024
                                                      ,9);
 rfPos->setLayout(ptn3);
                                                                             
 //设置入职记录器对象 一般对象名和传入的 字符是一样的
 salesDepart = &(Category::getInstance("salesDepart"));

 //设置优先级
 salesDepart->setPriority(Priority::ERROR);

 //此时布局设置好了也和目的地关联好了 记录器需要和目的地关联
 salesDepart->addAppender(pos);
 salesDepart->addAppender(fpos);
 salesDepart->addAppender(rfPos);


}
Mylogger::~Mylogger(){
    salesDepart->shutdown();
}
void test0()
{
    //第一步，完成单例模式的写法
    Mylogger *log = Mylogger::getInstance();
int cnt =10000;
while(cnt--){
    log->info("The log is info message");
    log->error("The log is error message");
    log->fatal("The log is fatal message");
    log->crit("The log is crit message");
}
}
void LogInfo(const string &msg){              
    Mylogger::getInstance()->info(msg.c_str());
}             
void LogError(const string &msg){              
    Mylogger::getInstance()->error(msg.c_str());
}             
void LogWarn(const string &msg){              
    Mylogger::getInstance()->warn(msg.c_str());
}             
void LogDebug(const string &msg){              
    Mylogger::getInstance()->debug(msg.c_str());
}             

void test1() 
{
    printf("hello,world\n");
    //第二步，像使用printf一样
    //只要求能输出纯字符串信息即可，不需要做到格式化输出
    LogInfo("The log is info message");
    LogError("The log is error message");
    LogWarn("The log is warn message");
    LogDebug("The log is debug message");
}
int main(){
    test0();
    test1();
}
